package com.imufe.chemicalenterprisedangerwarning.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

/**
 * 安全配置
 *
 * @author BaiBan
 * @since 2022/10/13
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private SecurityFilter securityFilter;

    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private CustomizeAccessDeniedHandler customizeAccessDeniedHandler;

    @Autowired
    AuthenticationSuccessHandler authenticationSuccessHandler;

    @Autowired
    AuthenticationFailureHandler authenticationFailureHandler;

    @Autowired
    LogoutSuccessHandler logoutSuccessHandler;

    @Autowired
    UserDetailsService securityUserService;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {

        // 关闭 csrf
        httpSecurity.cors()
                .and()
                    .csrf()
                    .disable()
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();

        registry
                .antMatchers("/user/login")
                    .anonymous()
                .antMatchers("/a", "/c")    // 不需要保护的资源路径允许访问
                    .hasRole("管理员")
                .antMatchers("/static/**",
                        "/swagger-resources/**", //swagger需要的静态资源路径
                        "/v2/**",
                        "/swagger-ui/**",
                        "**/upload/**",
                        "/index.jap",
                        "/**")
                    .permitAll()
                .anyRequest()               // 任何请求都需要认证
                    .authenticated();

        registry
                .and()
                    .exceptionHandling()
                    .authenticationEntryPoint(authenticationEntryPoint)
                    .accessDeniedHandler(customizeAccessDeniedHandler)
//                .and()
//                    .formLogin()
//                    .loginProcessingUrl("/user/login")
//                    .permitAll()  //允许所有用户
//                    .successHandler(authenticationSuccessHandler)  //登录成功处理逻辑
//                    .failureHandler(authenticationFailureHandler)  //登录失败处理逻辑
                .and()
                    .logout()
                    .permitAll()   //允许所有用户
                    .logoutSuccessHandler(logoutSuccessHandler)  //登出成功处理逻辑
                    .deleteCookies("JSESSIONID")   //登出之后删除cookie
//                 自定义权限拦截器JWT过滤器
                .and()
                    .addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class);

        return httpSecurity.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return securityUserService;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
